package io.gitee.zhucan123.core.infrastructure.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

/**
 * @author: zhuCan
 * @date: 2019/8/13
 * @description: 时间 处理类
 */
public class DateHandler {

  /**
   * Object instantiation is forbidden
   */
  private DateHandler() {

  }

  /**
   * 创建 线程局部变量  pattern : yyyy-MM-dd HH:mm:ss
   */
  private static volatile ThreadLocal<SimpleDateFormat> dateFormatThreadLocal;

  /**
   * 创建 线程局部变量  pattern : yyyyMMdd
   */
  private static volatile ThreadLocal<SimpleDateFormat> formatThreadLocal;


  private static DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

  private static DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");

  /**
   * 时间转换类 ,双检锁单例多线程副本模式
   *
   * @return
   */
  public static SimpleDateFormat fullDateFormatInstance() {
    if (dateFormatThreadLocal == null) {
      synchronized (DateHandler.class) {
        if (dateFormatThreadLocal == null) {
          dateFormatThreadLocal = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        }

      }
    }
    return dateFormatThreadLocal.get();
  }

  /**
   * 时间转换类 ,双检锁单例多线程副本模式
   *
   * @return
   */
  public static SimpleDateFormat noSpaceDateFormatInstance() {
    if (formatThreadLocal == null) {
      synchronized (DateHandler.class) {
        if (formatThreadLocal == null) {
          formatThreadLocal = ThreadLocal.withInitial(() -> {
            // 强制设定  +8时区
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
            dateFormat.setTimeZone(TimeZone.getTimeZone(ZoneId.of("+8")));
            formatThreadLocal.set(dateFormat);
            return dateFormat;
          });
        }

      }
    }
    return formatThreadLocal.get();
  }


  /**
   * 转换 时间 yyyyMMdd
   *
   * @param date
   * @return
   */
  public static String formatDate(Date date) {
    if (date == null) {
      return null;
    }
    return noSpaceDateFormatInstance().format(date);
  }

  /**
   * 获取当前时间 yyyyMMdd
   *
   * @return
   */
  public static String formatDate() {
    return dateFormatter.format(LocalDate.now());
  }

  /**
   * 转换 时间 yyyy-MM-dd HH:mm:ss
   *
   * @param date
   * @return
   */
  public static String formatFullDate(Date date) {
    if (date == null) {
      return null;
    }
    return fullDateFormatInstance().format(date);
  }

  /**
   * 获取当前时间 yyyy-MM-dd HH:mm:ss
   *
   * @return
   */
  public static String formatFullDate() {
    return dateTimeFormatter.format(LocalDateTime.now());
  }

  /**
   * 转换 时间 yyyy-MM-dd HH:mm:ss
   *
   * @param timestamp
   * @return
   */
  public static Date parseFullDate(String timestamp) throws ParseException {
    return fullDateFormatInstance().parse(timestamp);
  }

  /**
   * 获取 当前时间 不带时分秒
   *
   * @return
   */
  public static Date now() {
    LocalDate now = LocalDate.now();
    Calendar instance = Calendar.getInstance();
    instance.set(now.getYear(), now.getMonthValue() - 1, now.getDayOfMonth(), 0, 0, 0);
    return instance.getTime();
  }

  public static Date toDate(LocalDateTime dateTime) {
    return Date.from(dateTime.atZone(ZoneId.systemDefault()).toInstant());
  }

  public static LocalDateTime toLocal(Date date) {
    if (date == null) {
      return null;
    }
    return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();
  }

  public static long localMillis(LocalDateTime localDateTime) {
    return toDate(localDateTime).getTime();
  }

  public static LocalDateTime millisToLocal(long millis) {
    return Instant.ofEpochMilli(millis).atZone(ZoneId.systemDefault()).toLocalDateTime();
  }


}
